﻿using System;
//
using System.Management;

// SkypeScreenSaver, Copyright Mirosław M. Mączka.  All Rights Reserved. This code released under the terms of the Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.)

namespace SkypeScreenSaver
{
    class CWakeUpDisk:IWakeUp
    {
        //
        private ManagementEventWatcher w;
        private WqlEventQuery q;
        private ManagementOperationObserver observer;
        private ManagementScope scope;
        //
        public event WakeUpHandler eventWakeUp;
         //
        //==============================================================
        public CWakeUpDisk()
        {
            eventWakeUp = null;
            //
            w = null;
            observer = new  ManagementOperationObserver();

            // Bind to local machine
            ConnectionOptions opt = new ConnectionOptions();
            opt.EnablePrivileges = true; //sets required privilege
            scope = new ManagementScope( @"root\CIMV2", opt);
        }
        //==============================================================
        public bool Start()
        {
            try
            {
                //http://technet.microsoft.com/en-us/query/aa394173
                q = new WqlEventQuery();
                q.EventClassName = "__InstanceModificationEvent";
                q.WithinInterval = new TimeSpan(0, 0, 0, 1, 500);

                // DriveType - 5: CDROM
                q.Condition = @"TargetInstance ISA 'Win32_LogicalDisk' and (TargetInstance.DriveType = 2 or TargetInstance.DriveType = 5)";
                //q.Condition = @"TargetInstance ISA 'Win32_LogicalDisk'";
                w = new ManagementEventWatcher(scope, q);

                // register async. event handler
                w.EventArrived += new EventArrivedEventHandler(EventArrived);
                w.Start();
                SL.Log.FWrite("CWakeUpDisk.Start");
            }
            catch(Exception e)
            {
                SL.Log.FWrite("CWakeUpDisk.Start() Catch:{0}", e.Message);
                w = null;
            }
            return true;
        }
        //==============================================================
        public bool Stop()
        {
            if (null != w)
            {
                try
                {
                    w.EventArrived -= new EventArrivedEventHandler(EventArrived);
                    w.Stop();
                    w = null;
                    SL.Log.FWrite("CWakeUpDisk.Stop()");
                }
                catch(Exception e)
                {
                    SL.Log.FWrite("CWakeUpDisk.Stop() Catch:{0}", e.Message);
                    ;
                }
            }
            return true;
        }
        //==============================================================
        public string Info()
        {
            return @"root\CIMV2";
        }
        //==============================================================
        
        private void EventArrived(object sender, EventArrivedEventArgs e)
        {
            // Get the Event object and display it
            PropertyData pd = e.NewEvent.Properties["TargetInstance"];
            if (null == pd) return;

            ManagementBaseObject mbo = pd.Value as ManagementBaseObject;
            //SL.Log.Write("=>DriveType={0},Availability={1},MediaType={2},Status={3}", mbo.Properties["DriveType"].Value, mbo.Properties["Availability"].Value, mbo.Properties["MediaType"].Value, mbo.Properties["Status"].Value);

            // if CD removed VolumeName == null
            if (null != mbo.Properties["VolumeName"].Value)//tylko przy zamontowaniu napędu
            {
                if(null != eventWakeUp)
                {
                    eventWakeUp.Invoke();
                    SL.Log.Write("CWakeUpDisk Event");
                }
            }

        }
        //==============================================================
    }
}
